/**
 * lampara pingpong
 */

#include <18F2550.h>
#include "reg18f4550.h"

#ZERO_RAM
#CASE

#DEVICE HIGH_INTS=TRUE
//#DEVICE ADC=8
//#FUSES WDT4096                	// Watch Dog Timer a 4096/31KHz ~ 130 ms
#device CONST=ROM

#FUSES HS                   	// osc interno >= 8Mhz


#FUSES PUT                   	// Power Up Timer
//#FUSES PROTECT               	// Code protected from reads
//#FUSES CPB						// Code protected BootBlock
//#FUSES NOCPD                 	// No EE protection
#FUSES BROWNOUT					// Reset when brownout detected
//#FUSES BORV28					// Cuando caiga por debajo de 2.8V, se resetea
#define XTAL_OSC 8000000
#USE delay(clock=XTAL_OSC)


// conexion chips potencia

#bit SD_BLUE = hwLATB.0
#bit SD_GREEN = hwLATB.1
#bit SD_RED = hwLATB.2

#bit SD_SCK = hwLATC.0
#bit SD_OE = hwLATC.1
#bit SD_LE = hwLATC.2

typedef union
{
	struct
	{
		unsigned LD1R:1;
		unsigned LD1G:1;
		unsigned LD1B:1;

		unsigned LD2R:1;
		unsigned LD2G:1;
		unsigned LD2B:1;

		unsigned LD3R:1;
		unsigned LD3G:1;
		unsigned LD3B:1;

		unsigned LD4R:1;
		unsigned LD4G:1;
		unsigned LD4B:1;

		unsigned LD5R:1;
		unsigned LD6R:1;
		unsigned LD7R:1;
		unsigned LD8R:1;

		unsigned LD5G:1;
		unsigned LD6G:1;
		unsigned LD7G:1;
		unsigned LD8G:1;

		unsigned LD5B:1;
		unsigned LD6B:1;
		unsigned LD7B:1;
		unsigned LD8B:1;
	}  bit;
	
	int8 byte[3];	
}  led_sequence_t;


typedef struct
{
	unsigned R:1;
	unsigned G:1;
	unsigned B:1;
} ledfix_t;




typedef union
{
	struct
	{
		ledfix_t LD1, LD2, LD3, LD4, LD5, LD6, LD7, LD8;
	}  bit;
	
	int8 byte[3];	
}  led_sequence2_t;


const led_sequence_t ledtab[]=
{
	{1,0,0, 1,0,0, 1,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,1, 0,1,0, 1,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,1, 0,0,1, 0,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 0,1,0, 0,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,1,0, 1,0,0, 0,0,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,1, 1,1,0, 0,0,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,1,0, 1,1,1, 1,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 0,1,1, 0,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 0,0,1, 0,0,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,1,1, 0,1,1, 1,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 1,0,0, 1,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 0,1,0, 0,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,1,1, 1,0,1, 1,0,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,1,1, 1,1,1, 1,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,0, 1,1,1, 1,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{1,0,1, 1,0,0, 1,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,1,0, 1,0,1, 1,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,1,1, 0,1,0, 1,0,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,1,1, 0,1,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,1,1, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
	{0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0},
};	

led_sequence_t leds;	



void ld_out(void)
{
	SD_LE = 0;
	SD_SCK = 0;


	// LED8

	SD_RED = leds.bit.LD8R;
	SD_GREEN = leds.bit.LD8G;
	SD_BLUE = leds.bit.LD8B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED7

	SD_RED = leds.bit.LD7R;
	SD_GREEN = leds.bit.LD7G;
	SD_BLUE = leds.bit.LD7B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED6

	SD_RED = leds.bit.LD6R;
	SD_GREEN = leds.bit.LD6G;
	SD_BLUE = leds.bit.LD6B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED5

	SD_RED = leds.bit.LD5R;
	SD_GREEN = leds.bit.LD5G;
	SD_BLUE = leds.bit.LD5B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED4

	SD_RED = leds.bit.LD4R;
	SD_GREEN = leds.bit.LD4G;
	SD_BLUE = leds.bit.LD4B;
	SD_SCK = 1;
	SD_SCK = 0;


	// LED3

	SD_RED = leds.bit.LD3R;
	SD_GREEN = leds.bit.LD3G;
	SD_BLUE = leds.bit.LD3B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED2

	SD_RED = leds.bit.LD2R;
	SD_GREEN = leds.bit.LD2G;
	SD_BLUE = leds.bit.LD2B;
	SD_SCK = 1;
	SD_SCK = 0;

	// LED1

	SD_RED = leds.bit.LD1R;
	SD_GREEN = leds.bit.LD1G;
	SD_BLUE = leds.bit.LD1B;
	SD_SCK = 1;
	SD_SCK = 0;

	// pulso de carga

	SD_LE = 1;
	SD_LE = 0;

}	

void sd_out( int8 red, int8 green, int8 blue)
{
	SD_SCK = 0;
	SD_LE = 0;

	// bit 0
	#asm
	btfss red,0
	bsf SD_RED
	btfsc red,0
	bcf SD_RED

	btfss green,0
	bsf SD_GREEN
	btfsc green,0
	bcf SD_GREEN

	btfss blue,0
	bsf SD_BLUE
	btfsc blue,0
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 1
	#asm
	btfss red,0
	bsf SD_RED
	btfsc red,0
	bcf SD_RED

	btfss green,0
	bsf SD_GREEN
	btfsc green,0
	bcf SD_GREEN

	btfss blue,0
	bsf SD_BLUE
	btfsc blue,0
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 0
	#asm
	btfss red,0
	bsf SD_RED
	btfsc red,0
	bcf SD_RED

	btfss green,0
	bsf SD_GREEN
	btfsc green,0
	bcf SD_GREEN

	btfss blue,0
	bsf SD_BLUE
	btfsc blue,0
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 1
	#asm
	btfss red,1
	bsf SD_RED
	btfsc red,1
	bcf SD_RED

	btfss green,1
	bsf SD_GREEN
	btfsc green,1
	bcf SD_GREEN

	btfss blue,1
	bsf SD_BLUE
	btfsc blue,1
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 2
	#asm
	btfss red,2
	bsf SD_RED
	btfsc red,2
	bcf SD_RED

	btfss green,2
	bsf SD_GREEN
	btfsc green,2
	bcf SD_GREEN

	btfss blue,2
	bsf SD_BLUE
	btfsc blue,2
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 3
	#asm
	btfss red,3
	bsf SD_RED
	btfsc red,3
	bcf SD_RED

	btfss green,3
	bsf SD_GREEN
	btfsc green,3
	bcf SD_GREEN

	btfss blue,3
	bsf SD_BLUE
	btfsc blue,3
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 4
	#asm
	btfss red,4
	bsf SD_RED
	btfsc red,4
	bcf SD_RED

	btfss green,4
	bsf SD_GREEN
	btfsc green,4
	bcf SD_GREEN

	btfss blue,4
	bsf SD_BLUE
	btfsc blue,4
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 5
	#asm
	btfss red,5
	bsf SD_RED
	btfsc red,5
	bcf SD_RED

	btfss green,5
	bsf SD_GREEN
	btfsc green,5
	bcf SD_GREEN

	btfss blue,5
	bsf SD_BLUE
	btfsc blue,5
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 6
	#asm
	btfss red,6
	bsf SD_RED
	btfsc red,6
	bcf SD_RED

	btfss green,6
	bsf SD_GREEN
	btfsc green,6
	bcf SD_GREEN

	btfss blue,6
	bsf SD_BLUE
	btfsc blue,6
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;

	// bit 7
	#asm
	btfss red,7
	bsf SD_RED
	btfsc red,7
	bcf SD_RED

	btfss green,7
	bsf SD_GREEN
	btfsc green,7
	bcf SD_GREEN

	btfss blue,7
	bsf SD_BLUE
	btfsc blue,7
	bcf SD_BLUE
	#endasm

	SD_SCK = 1;
	SD_SCK = 0;



}	

void hw_setup(void)
{
	port_b_pullups(FALSE);

	hwLATB  = 0b00000000;
	hwTRISB = 0b00000000;

	hwLATC  = 0b00000010;
	hwTRISC = 0b00000000;
}


void main( void )
{
	int8 i;
	//hwOSCCON = 0b01110010;
	hw_setup();
	
	leds.byte[0]=0;
	leds.byte[1]=0;
	leds.byte[2]=0;
	ld_out();
	SD_OE = 0;

	for(;;)
	{
		for (i=0;i<22;i++)
		{
			leds.byte[0] = ledtab[i].byte[0];
			leds.byte[1] = ledtab[i].byte[1];
			leds.byte[2] = ledtab[i].byte[2];
			ld_out();
			delay_ms(100);
		}	
	}
}